﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace QW.Core.Helper
{
    public class HtmlTagHelper
    {
        /// <summary>
        /// 清除HTML中的JS脚本和style脚本
        /// </summary>
        /// <param name="htmlText"></param>
        /// <returns></returns>
        public static string RemoveScriptsAndStyle(string htmlText)
        {
            htmlText = RemoveScriptTag(htmlText);
            htmlText = RemoveStyleTag(htmlText);
            return htmlText;
        }
        /// <summary>
        /// 清除所有空格
        /// <para>包括html空格</para>
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string RemoveAllSpace(string str)
        {
            str = Regex.Replace(str, @"\s", string.Empty, RegexOptions.IgnoreCase);
            str = Regex.Replace(str, @"&nbsp;", string.Empty, RegexOptions.IgnoreCase);
            return str;
        }
        /// <summary>
        /// 简单编码
        /// </summary>
        /// <param name="str">源字符串</param>
        /// <returns></returns>
        public static string SimpleEncode(string str)
        {
            str = str.Replace("&", "&amp;");
            str = str.Replace("'", "&#39;");
            str = str.Replace("\"", "&quot;");
            str = str.Replace(" ", "&nbsp;");
            str = str.Replace("<", "&lt;");
            str = str.Replace(">", "&gt;");
            str = str.Replace("\n", "<br>");
            str = str.Replace("\r", "<br>");
            str = str.Replace("\r\n", "<br>");
            return str;
        }
        /// <summary>
        /// 简单解码
        /// </summary>
        /// <param name="str">要解码的字符串</param>
        /// <returns></returns>
        public static string SimpleDecode(string str)
        {
            str = str.Replace("<br>", "\n");
            str = str.Replace("&gt;", ">");
            str = str.Replace("&lt;", "<");
            str = str.Replace("&nbsp;", " ");
            str = str.Replace("&quot;", "\"");
            str = str.Replace("&amp;", "&");
            str = str.Replace("&#39;", "'");
            return str;
        }

        #region 移除HTML标签
        /// <summary>
        /// 移除HTML标签
        /// </summary>
        /// <param name="html"></param>
        /// <param name="unRemoveTags"></param>
        /// <returns></returns>
        public static string RemoveTag(string html, string[] unRemoveTags = null)
        {
            if (unRemoveTags == null)
            {
                unRemoveTags = new string[] { "p", "b", "em", "a", "strong", "img" };
            }
            string[] otherTags = new string[] { "!doctype html", "base", "!", "object" };

            html = Regex.Replace(html, @" <!--([^(-){2}])*-->", "");//过滤注释
            foreach (string e in otherTags)
            {
                if (!unRemoveTags.Contains(e.ToString()))
                {
                    html = Regex.Replace(html, TagRegex.Remove(e.ToString()), "");
                }
            }

            Array array = Enum.GetValues(typeof(HtmlTagByAll));
            foreach (Enum e in array)
            {
                if (!unRemoveTags.Contains(e.ToString()))
                {
                    html = Regex.Replace(html, TagRegex.RemoveAll(e.ToString()), "");
                }
            }

            array = Enum.GetValues(typeof(HtmlTag));
            foreach (Enum e in array)
            {
                if (!unRemoveTags.Contains(e.ToString()))
                {
                    html = Regex.Replace(html, TagRegex.Remove(e.ToString()), "");
                }
            }
            return html;
        }


        /// <summary>
        /// 移除Script代码
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public static string RemoveScriptTag(string htmlText)
        {
            htmlText = Regex.Replace(htmlText, @"<\s*script[^>]*?>.*?<\s*/\s*script\s*>", "", RegexOptions.IgnoreCase);
            return htmlText;
        }
        /// <summary>
        /// 清除style脚本
        /// </summary>
        /// <param name="htmlText"></param>
        /// <returns></returns>
        public static string RemoveStyleTag(string htmlText)
        {
            htmlText = Regex.Replace(htmlText, @"<\s*style[^>]*?>.*?<\s*/\s*style\s*>", "", RegexOptions.IgnoreCase);
            return htmlText;
        }
        /// <summary>
        /// 移除Div代码
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public static string RemoveDivTag(string text)
        {
            text = Regex.Replace(text, @"<[\/]{0,1}(div [^<>]*>)|<[\/]{0,1}(div>)", "");
            return text;
        }
        /// <summary>
        /// 移除Iframe代码
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public static string RemoveIframeTag(string text)
        {
            text = Regex.Replace(text, @"(<iframe){1,}[^<>]*>[^\0]*(<\/iframe>){1,}", "");
            return text;
        }
        #endregion

    }
    /// <summary>
    /// 标签正则
    /// </summary>
    public class TagRegex
    {
        /// <summary>
        /// 移除
        /// </summary>
        /// <param name="tag"></param>
        /// <returns></returns>
        public static string Remove(string tag)
        {
            return @"<[\/]{0,1}(" + tag + @" [^<>]*>)|<[\/]{0,1}(" + tag + ">)";
        }
        /// <summary>
        /// 移除所有
        /// </summary>
        /// <param name="tag"></param>
        /// <returns></returns>
        public static string RemoveAll(string tag)
        {
            return @"<" + tag + @"([^>])*>(\w|\W)*?</" + tag + "([^>])*>";//@"(<" + tag + @"){1,}[^<>]*>[^\0]*(<\/" + tag + ">){1,}";
        }
    }
    /// <summary>
    /// 将移除全部标签
    /// </summary>
    public enum HtmlTagByAll
    {
        /// <summary>
        /// 文档的样式信息
        /// </summary>
        style,
        /// <summary>
        /// 内联框架
        /// </summary>
        iframe,
        /// <summary>
        /// 客户端脚本
        /// </summary>
        script,
    }
    /// <summary>
    /// 只移除标签，保留内容
    /// </summary>
    public enum HtmlTag
    {
        //!--...--,//注释    
        /// <summary>
        /// 锚
        /// </summary>
        a,
        /// <summary>
        /// 缩写
        /// </summary>
        abbr,
        /// <summary>
        /// 只取首字母的缩写
        /// </summary>
        acronym,  
        address,//文档作者或拥有者的联系信息    
        applet,//不赞成使用。嵌入的 applet    
        area,//图像地图内部的区域    
        b,//粗体文本    
          //base,//页面中所有链接的默认地址或默认目标    
        baseont,//不赞成使用。页面中文本的默认字体、颜色或尺寸    
        bdo,//文本的方向    
        big,//大号文本    
        blockquote,//块引用    
        body,//文档的主体    
        br,//简单的折行    
        button,//按钮    
        caption,//表格标题    
        center,//不赞成使用。居中文本    
        cite,//引用(citation)    
        code,//计算机代码文本    
        col,//表格中一个或多个列的属性值    
        colgroup,//表格中供格式化的列组    
        dd,//列表中项目的描述    
        del,//被删除文本    
        dir,//不赞成使用。目录列表    
        div,//文档中的节    
        dl,//列表    
        dn,//项目    
           //DOCTYPE,// 文档类型  
        dt,//列表中的项目    
        em,//强调文本  
        form,
        h1,// to h6,// HTML 标题
        h2,
        h3,
        h4,
        h5,
        h6,
        head,//关于文档的信息    
        hr,//水平线    
        html,// HTML 文档    
        i,//斜体文本    
        ieldset,//围绕表单中元素的边框    
        img,//图像    
        input,//输入控件    
        ins,//被插入文本    

        isindex,//不赞成使用。与文档相关的可搜索索引    
        kbd,//键盘文本    
        label,// input 元素的标注    
        legend,// ieldset 元素的标题    
        li,//列表的项目    
        link,//文档与外部资源的关系    
        map,//图像映射    
        menu,//不赞成使用。菜单列表    
        meta,//关于 HTML 文档的元信息    
        norames,//针对不支持框架的用户的替代内容    
        noscript,//针对不支持客户端脚本的用户的替代内容    
                 //object,//嵌入的对象    
        ol,//有序列表    
        ont,//不赞成使用。文本的字体、尺寸和颜色      
        oot,//表格中的表注内容（脚注）    
        optgroup,//选择列表中相关选项的组合    
        option,//选择列表中的选项    
        orm,//供用户输入的 HTML 表单    
        p,//段落    
        param,//对象的参数。
        pre,//预格式文本      
        q,//短的引用    
        rame,//框架集的窗口或框架    
        rameset,//框架集    
        s,//不赞成使用。加删除线的文本    
        samp,//计算机代码样本    

        select,//选择列表（下拉列表）    
        small,//小号文本    
        span,//文档中的节    
        strike,//不赞成使用。加删除线的文本    
        strong,//语气更为强烈的强调文本    
        sub,//下标文本    
        sup,//上标文本    
        table,//表格      
        tbody,//表格中的主体内容    
        td,//表格中的单元    
        textarea,//多行的文本输入控件    
        th,//表格中的表头单元格    
        thead,//表格中的表头内容    
        title,//文档的标题    
        tr,//表格中的行    
        tt,//打字机文本    
        u,//不赞成使用。下划线文本    
        ul,//无序列表    
        var,//文本的变量部分    
        xmp,//不赞成使用。预格式文本     
    }
}
